﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using PMisuseAn.io;
using PMisuseAn.behaviour.model;

using System.IO;
using System.Collections;
using System.Collections.ObjectModel;
using Microsoft.Msagl.GraphViewerGdi;
using Microsoft.Msagl.Drawing;
using PMisuseAn.util;

namespace PMisuseAn
{
    /// <summary>
    /// Interaction logic for ContextInterface.xaml
    /// </summary>
    public partial class ContextInterface : Page
    {
        public static ContextInterface ci = new ContextInterface();
        GViewer viewer = new GViewer();
        string startState;
        string endState;
        StateMachine machine_;

        double progressValue = 0;
        UpdateProgressBarDelegate updatePbDelegate;

        public ContextInterface()
        {
            InitializeComponent();
            tabControl1.Visibility = System.Windows.Visibility.Hidden;
            fsm_grid.Visibility = System.Windows.Visibility.Hidden;
            loadProjectNamesToMenu();
        }

        public void loadContextInterface()
        {
            InitializeComponent();
            initProgress();

            tabControl1.Visibility = System.Windows.Visibility.Visible;
            fsm_grid.Visibility = System.Windows.Visibility.Visible;
            loadProjectNamesToMenu();
            UpdateProgressBar();
            project_name_l.Content = MainWindow.clusterName;

            //load misuse analysis objects
            loadActors();
            UpdateProgressBar();
            loadDomainAttributes();
            UpdateProgressBar();
            loadPolicyStatements();
            UpdateProgressBar();
            //loadMachines();
            loadFiniteStatemachines();
            removeProgressBar();
        }

        public void loadDomainAttributes()
        {
            List<Attribute> attributes = MisUseAnObjectsDB.loadAllAttributes(MainWindow.clusterName);
            attributes_lb.Items.Clear();

            int att_no = 1;
            foreach (Attribute att in attributes)
            {
                ListBoxItem l = new ListBoxItem();
                StackPanel s = new StackPanel();
                s.Orientation = System.Windows.Controls.Orientation.Horizontal;

                ContentPresenter c1 = new ContentPresenter();
                c1.Content = att_no;
                att_no = att_no + 1;

                ContentPresenter c2 = new ContentPresenter();

                Button open_att_b = new Button();
                open_att_b.Tag = att;
                open_att_b.Style = (System.Windows.Style)FindResource("LinkButton");
                open_att_b.Height = 15;
                open_att_b.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                open_att_b.VerticalAlignment = System.Windows.VerticalAlignment.Top;
                open_att_b.Content = att.name;
                open_att_b.AddHandler(Button.ClickEvent, new RoutedEventHandler(open_att_b_Click));

                c2.Content = open_att_b;

                if (attributes_lb.Items.Count % 2 == 0)
                {
                    l.Background = Brushes.AliceBlue;
                }

                c1.Width = 15;
                c2.Width = attributes_lb.Width - 40;
                s.Children.Add(c1);
                s.Children.Add(c2);

                //add context menu to item to clone state machine
                //use cloneStateMachineDB method in DB class

                ContextMenu cm = new System.Windows.Controls.ContextMenu();
                cm.Height = 64;
                cm.Width = 136;

                MenuItem cm_d = new MenuItem();
                cm_d.Header = "Delete";
                cm_d.Tag = att;
                cm_d.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(del_att_Click));
                cm_d.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                cm_d.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Right;
                cm_d.FontSize = 12;
                cm_d.Foreground = Brushes.DarkGreen;

                BitmapImage cm_d_image = new BitmapImage();
                cm_d_image.BeginInit();
                Uri cm_d_Uri = new Uri("/PMisuseAn;component/images/DeleteHS.png", UriKind.RelativeOrAbsolute);
                cm_d_image.UriSource = cm_d_Uri;
                cm_d_image.EndInit();

                Image cm_d_iconImage = new Image();
                cm_d_iconImage.Source = cm_d_image;
                cm_d.Icon = cm_d_iconImage;

                cm.Items.Add(cm_d);
                l.ContextMenu = cm;

                l.Content = s;
                l.Tag = att;

                attributes_lb.Items.Add(l);
            }  
        }

        public void loadPolicyStatements()
        {
            List<Policy> policy_statements = MisUseAnObjectsDB.loadAllPolicyStatementsFull(MainWindow.clusterName);

            if (policy_statements != null)
            {
                policies_lb.Items.Clear();
                int pol_no = 1;

                foreach (Policy policy in policy_statements)
                {
                    ListBoxItem l = new ListBoxItem();
                    l.FontSize = 10.5;
                    StackPanel s = new StackPanel();
                    s.Orientation = System.Windows.Controls.Orientation.Horizontal;

                    ContentPresenter c1 = new ContentPresenter();
                    c1.Content = pol_no + ".";
                    pol_no = pol_no + 1;

                    ContentPresenter c2 = new ContentPresenter();
                    c2.Content = " [TP:" + policy.transmissionPrinciple + "]";

                    ContentPresenter c3 = new ContentPresenter();

                    if (!policy.statement.Equals("DO[NILL]"))
                    {
                        ListBox lb2 = new ListBox();
                        lb2.FontSize = 10.5;

                        PolicyStatementAnalyser psa = new PolicyStatementAnalyser();
                        psa.ifThenUnlessTokenisation(policy.statement);

                        ListBoxItem lb2l1 = new ListBoxItem();
                        
                        string if_content = "IF" + psa.if_content;
                        TextBlock tb1 = new TextBlock();
                        tb1.Text = if_content;
                        tb1.Width = policies_lb.Width - 146;
                        tb1.TextWrapping = TextWrapping.Wrap;

                        lb2l1.Content = tb1;
                        lb2.Items.Add(lb2l1);

                        ListBoxItem lb2l2 = new ListBoxItem();
                        string then_content = "   THEN" + psa.then_content;
                        TextBlock tb2 = new TextBlock();
                        tb2.Text = then_content;
                        tb2.Width = policies_lb.Width - 146;
                        tb2.TextWrapping = TextWrapping.Wrap;

                        lb2l2.Content = tb2;
                        lb2.Items.Add(lb2l2);
                        if (psa.unless_content != null)
                        {
                            ListBoxItem lb2l3 = new ListBoxItem();
                            string unless_content = "   UNLESS" + psa.unless_content;
                            TextBlock tb3 = new TextBlock();
                            tb3.Text = unless_content;
                            tb3.Width = policies_lb.Width - 146;
                            tb3.TextWrapping = TextWrapping.Wrap;

                            lb2l3.Content = tb3;
                            lb2.Items.Add(lb2l3);
                        }

                        if (policies_lb.Items.Count % 2 == 0)
                        {
                            l.Background = Brushes.AliceBlue;

                            lb2.Background = Brushes.AliceBlue;
                            lb2.BorderBrush = Brushes.AliceBlue;
                        }
                        else
                        {
                            lb2.BorderBrush = Brushes.White;
                        }
                        c3.Content = lb2;
                    }
                    else
                    {
                        c3.Content = policy.statement;
                        if (policies_lb.Items.Count % 2 == 0)
                        {
                            l.Background = Brushes.AliceBlue;
                            l.Foreground = Brushes.DarkRed;
                        }
                    }

                    c1.Width = 15;
                    c2.Width = 98;
                    c3.Width = policies_lb.Width - 140;
                    s.Children.Add(c1);
                    s.Children.Add(c2);
                    s.Children.Add(c3);

                    //add context menu to item to clone state machine
                    //use cloneStateMachineDB method in DB class

                    ContextMenu cm = new System.Windows.Controls.ContextMenu();
                    cm.Height = 64;
                    cm.Width = 136;

                    MenuItem cm_d = new MenuItem();
                    cm_d.Header = "Delete";
                    cm_d.Tag = policy;
                    cm_d.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(del_policy_statement_b_Click));
                    cm_d.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                    cm_d.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Right;
                    cm_d.FontSize = 12;
                    cm_d.Foreground = Brushes.DarkGreen;

                    BitmapImage cm_d_image = new BitmapImage();
                    cm_d_image.BeginInit();
                    Uri cm_d_Uri = new Uri("/PMisuseAn;component/images/DeleteHS.png", UriKind.RelativeOrAbsolute);
                    cm_d_image.UriSource = cm_d_Uri;
                    cm_d_image.EndInit();

                    Image cm_d_iconImage = new Image();
                    cm_d_iconImage.Source = cm_d_image;
                    cm_d.Icon = cm_d_iconImage;

                    cm.Items.Add(cm_d);
                    l.ContextMenu = cm;

                    l.Content = s;
                    l.Tag = policy;

                    policies_lb.Items.Add(l);
                }
            }
        }

        void del_policy_statement_b_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show("Confirm delete...", "Delete", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (result == MessageBoxResult.No)
            {
                return;
            }
            MenuItem d_b = (MenuItem)sender;
            Policy tag_id = (Policy)d_b.Tag;

            MisUseAnObjectsDB.deletePolicyStatement(tag_id.statement, tag_id.transmissionPrinciple, MainWindow.clusterName);
            loadPolicyStatements();
        } 

        public void loadActors()
        {
            List<string> actors = MisUseAnObjectsDB.loadActorNames(MainWindow.clusterName);
            actors_lb.Items.Clear();

            int act_no = 1;
            foreach (string actorName in actors)
            {
                ListBoxItem l = new ListBoxItem();
                StackPanel s = new StackPanel();
                s.Orientation = System.Windows.Controls.Orientation.Horizontal;

                ContentPresenter c1 = new ContentPresenter();
                c1.Content = act_no;
                act_no = act_no + 1;

                ContentPresenter c2 = new ContentPresenter();

                Button open_actor_b = new Button();
                open_actor_b.Tag = actorName;
                open_actor_b.Style = (System.Windows.Style)FindResource("LinkButton");
                open_actor_b.Height = 17;
                open_actor_b.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                open_actor_b.VerticalAlignment = System.Windows.VerticalAlignment.Top;
                open_actor_b.Content = actorName;
                open_actor_b.AddHandler(Button.ClickEvent, new RoutedEventHandler(open_actor_b_Click));

                c2.Content = open_actor_b;

                if (actors_lb.Items.Count % 2 == 0)
                {
                    l.Background = Brushes.AliceBlue;
                }

                c1.Width = 15;
                c2.Width = fsm_lb.Width - 40;
                s.Children.Add(c1);
                s.Children.Add(c2);

                //add context menu to item to clone state machine
                //use cloneStateMachineDB method in DB class

                ContextMenu cm = new System.Windows.Controls.ContextMenu();
                cm.Height = 64;
                cm.Width = 136;

                MenuItem cm_d = new MenuItem();
                cm_d.Header = "Delete";
                cm_d.Tag = actorName;
                cm_d.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(del_actor_Click));
                cm_d.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                cm_d.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Right;
                cm_d.FontSize = 12;
                cm_d.Foreground = Brushes.DarkGreen;

                BitmapImage cm_d_image = new BitmapImage();
                cm_d_image.BeginInit();
                Uri cm_d_Uri = new Uri("/PMisuseAn;component/images/DeleteHS.png", UriKind.RelativeOrAbsolute);
                cm_d_image.UriSource = cm_d_Uri;
                cm_d_image.EndInit();

                Image cm_d_iconImage = new Image();
                cm_d_iconImage.Source = cm_d_image;
                cm_d.Icon = cm_d_iconImage;

                cm.Items.Add(cm_d);
                l.ContextMenu = cm;

                l.Content = s;
                l.Tag = actorName;

                actors_lb.Items.Add(l);
            }





            ////////////////
            //int no_actor = 1;
            //foreach(string actorName in actors)
            //{               
            //    TableRow tr_super = new TableRow();
            //    tr_super.Tag = actorName;
            //    Paragraph p1 = new Paragraph(new Run(""+no_actor));
            //    no_actor = no_actor + 1;
            //    p1.FontSize = 10;
            //    p1.FontWeight = FontWeights.Light;
            //    tr_super.Cells.Add(new TableCell(p1));
                
            //    Button open_actor_b = new Button();
            //    open_actor_b.Tag = actorName;
            //    open_actor_b.Style = (System.Windows.Style)FindResource("LinkButton");
            //    open_actor_b.Height = 17;
            //    open_actor_b.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
            //    open_actor_b.VerticalAlignment = System.Windows.VerticalAlignment.Top;
            //    open_actor_b.Content = actorName;
            //    open_actor_b.AddHandler(Button.ClickEvent, new RoutedEventHandler(open_actor_b_Click));

            //    InlineUIContainer myInlineUIContainer_open_actor_b = new InlineUIContainer();
            //    myInlineUIContainer_open_actor_b.Child = open_actor_b;

            //    Paragraph p2 = new Paragraph(myInlineUIContainer_open_actor_b);
            //    p2.FontSize = 10;
            //    p2.FontWeight = FontWeights.Light;
            //    tr_super.Cells.Add(new TableCell(p2));

            //    Image del = new Image();
            //    //del.Source = new BitmapImage(new Uri(@"images\delete.png", UriKind.RelativeOrAbsolute));
            //    del.Height = 6;
            //    del.Width = 6;

            //    Button del_b = new Button();
            //    del_b.Tag = actorName;
            //    del_b.Background = Brushes.WhiteSmoke;
            //    del_b.Content = del;
            //    del_b.AddHandler(Button.ClickEvent, new RoutedEventHandler(del_actor_Click));

            //    InlineUIContainer myInlineUIContainer_del_b = new InlineUIContainer();
            //    myInlineUIContainer_del_b.Child = del_b;
            //    Paragraph p3 = new Paragraph(myInlineUIContainer_del_b);
            //    p3.FontSize = 10;
            //    p3.FontWeight = FontWeights.Light;
            //    tr_super.Cells.Add(new TableCell(p3));

            //    actors_trg.Rows.Add(tr_super);
            //}
            //int numberOfRows = actors_trg.Rows.Count;
            //for (int x = 0; x < numberOfRows; x++)
            //{
            //    // Set alternating background colors for the middle colums.
            //    if (x % 2 == 0)
            //        actors_trg.Rows[x].Background = Brushes.White;
            //    else
            //        actors_trg.Rows[x].Background = Brushes.GhostWhite;
            //}
        }

        public void loadFiniteStatemachines()
        {
            int fsm_no = 1;
            fsm_lb.Items.Clear();
            List<string> machines = MisUseAnObjectsDB.loadAllmachines(MainWindow.clusterName);

            progressBar1.Maximum = progressBar1.Maximum + machines.Count();
            
            foreach (string stateMachine in machines)
            {
                UpdateProgressBar();

                ListBoxItem l = new ListBoxItem();                
                StackPanel s = new StackPanel();
                s.Orientation = System.Windows.Controls.Orientation.Horizontal;
               
                ContentPresenter c1 = new ContentPresenter();
                c1.Content = fsm_no;
                fsm_no = fsm_no + 1;

                Button open_state_machine_b = new Button();
                open_state_machine_b.Tag = stateMachine;
                open_state_machine_b.Style = (System.Windows.Style)FindResource("LinkButton");
                open_state_machine_b.Height = 16;
                open_state_machine_b.FontSize = 11;
                open_state_machine_b.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                open_state_machine_b.VerticalAlignment = System.Windows.VerticalAlignment.Top;
                open_state_machine_b.Content = stateMachine;
                open_state_machine_b.AddHandler(Button.ClickEvent, new RoutedEventHandler(open_state_machine_b_Click));
                ContentPresenter c2 = new ContentPresenter();
                c2.Content = open_state_machine_b;

                //Image del = new Image();
                ////del.Source = new BitmapImage(new Uri(@"images\delete.png", UriKind.RelativeOrAbsolute));
                //del.Height = 4;
                //del.Width = 5;

                //Button del_b = new Button();
                //del_b.Tag = stateMachine;
                //del_b.Background = Brushes.WhiteSmoke;
                //del_b.Content = del;
                //del_b.AddHandler(Button.ClickEvent, new RoutedEventHandler(del_state_machine_Click));
                
                ContentPresenter c3 = new ContentPresenter();
                ListBox lbc3 = new ListBox();
                List<Agent> mc_agents = MisUseAnObjectsDB.loadGroupAgentDBMachine(stateMachine, MainWindow.clusterName);
                if (mc_agents.Count == 0)
                {
                    ListBoxItem lbi = new ListBoxItem();
                    string content = "[unassigned]";
                    lbi.Content = content;
                    lbi.Foreground = Brushes.Red;
                    lbc3.Items.Add(lbi);
                }
                else
                {
                    foreach (Agent a in mc_agents)
                    {
                        ListBoxItem lbi = new ListBoxItem();
                        string content = "ownedBy(agent[" + a.agentName + "]" + " inGroup[";
                        int i = 1;
                        foreach (string gm in a.associatedGroups)
                        {
                            content = content + gm;
                            if (i < a.associatedGroups.Count())
                            {
                                content = content + ", ";
                            }
                            i = i + 1;
                        }
                        content = content + "])";
                        lbi.Content = content;
                        lbi.Tag = content;

                        bool contained = false;
                        foreach (ListBoxItem item in lbc3.Items)
                        {
                            string cx = (string)item.Tag;
                            if (cx.Equals(content))
                            {
                                contained = true;
                                break;
                            }
                        }
                        if (!contained)
                        {
                            lbc3.Items.Add(lbi);
                        }
                    }
                }
                
                lbc3.BorderThickness = new Thickness(0);
                if (fsm_lb.Items.Count % 2 == 0)
                {
                    lbc3.Background = Brushes.AliceBlue;
                }

                c3.Content = lbc3;

                c1.Width = 15;
                c2.Width = fsm_lb.Width - 430;
                c3.Width = 378;
                s.Children.Add(c1);
                s.Children.Add(c2);
                s.Children.Add(c3);

                //add context menu to item to clone state machine
                //use cloneStateMachineDB method in DB class
                
                ContextMenu cm = new System.Windows.Controls.ContextMenu();
                cm.Height = 64;
                cm.Width = 136; 

                MenuItem cm_i = new MenuItem();
                cm_i.Header = "Clone ";
                cm_i.Tag = stateMachine;
                cm_i.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(clone_clicked));
                cm_i.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                cm_i.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Right;
                cm_i.FontSize = 12;
                cm_i.Foreground = Brushes.DarkGreen;

                BitmapImage cm_i_image = new BitmapImage();
                cm_i_image.BeginInit();
                Uri cm_i_Uri = new Uri("/PMisuseAn;component/images/clone.png", UriKind.RelativeOrAbsolute);
                cm_i_image.UriSource = cm_i_Uri;
                cm_i_image.EndInit();

                Image cm_i_iconImage = new Image();
                cm_i_iconImage.Source = cm_i_image;
                cm_i.Icon = cm_i_iconImage;


                MenuItem cm_d = new MenuItem();
                cm_d.Header = "Delete";
                cm_d.Tag = stateMachine;
                cm_d.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(del_state_machine_menu_Clicked));
                cm_d.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
                cm_d.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Right;
                cm_d.FontSize = 12;
                cm_d.Foreground = Brushes.DarkGreen;

                BitmapImage cm_d_image = new BitmapImage();
                cm_d_image.BeginInit();
                Uri cm_d_Uri = new Uri("/PMisuseAn;component/images/DeleteHS.png", UriKind.RelativeOrAbsolute);
                cm_d_image.UriSource = cm_d_Uri;
                cm_d_image.EndInit();

                Image cm_d_iconImage = new Image();
                cm_d_iconImage.Source = cm_d_image;
                cm_d.Icon = cm_d_iconImage;

                cm.Items.Add(cm_i);
                cm.Items.Add(cm_d);
                l.ContextMenu = cm;

                l.Content = s;
                l.Tag = stateMachine;
                l.AddHandler(ListBoxItem.SelectedEvent, new RoutedEventHandler(fsm_lb_item_selected));

                if (fsm_lb.Items.Count % 2 == 0)
                {
                    l.Background = Brushes.AliceBlue;
                }

                fsm_lb.Items.Add(l); 
            }           

        }

        public string cloneMachineName = null;
        private void clone_clicked(object sender, RoutedEventArgs e)
        {
            MenuItem cm_i = (MenuItem)sender;
            string originalMachineName = (string)cm_i.Tag;

            CloneAsWindow caw = new CloneAsWindow(this, originalMachineName);
            caw.Owner = (Window)this.Parent;
            caw.ShowDialog();

            if (cloneMachineName != null)
            {
                MisUseAnObjectsDB.cloneStateMachineDB(originalMachineName, cloneMachineName, MainWindow.clusterName);
            }
            loadFiniteStatemachines();
        }

        public void del_state_machine_menu_Clicked(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show("Confirm delete...", "Delete", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (result == MessageBoxResult.No)
            {
                return;
            }

            MenuItem cm_i = (MenuItem)sender;
            string machineName = (string)cm_i.Tag;
            MisUseAnObjectsDB.deleteStateMachineDB(machineName, MainWindow.clusterName);

            //machines_trg.Rows.Clear();
            fsm_lb.Items.Clear();
            //loadMachines();
            loadFiniteStatemachines();
        }

        public void fsm_lb_item_selected(object sender, RoutedEventArgs e)
        {
            ListBoxItem a_i = (ListBoxItem)sender;
            string machine_name = (String)a_i.Tag;
            genStateMachineGraph(machine_name);
        }

        void genStateMachineGraph(string machineName)
        {
            InitializeComponent();
            
            //Serialize(fsm);
            Graph glee_fsm_graph = CreateFSMGraph(machineName);
                        
            glee_fsm_graph.Attr.LayerDirection = LayerDirection.None;
            glee_fsm_graph.Attr.AspectRatio = 1.5;

            Hashtable nodes = glee_fsm_graph.NodeMap;
            ICollection<Edge> edges = glee_fsm_graph.Edges;

            
            //remove nodes with no in or out
            foreach (State x_state in machine_.states)
            {
                string x_key = null;
                foreach (DictionaryEntry entry in nodes)
                {
                    Node n = (Node)entry.Value;
                    if (n.LabelText.Equals(x_state.name))
                    {
                        x_key = (string)entry.Key;
                        break;
                    }
                }
                Node x_node = glee_fsm_graph.FindNode(x_key);
                if (x_node.InEdges.Count() == 0 && x_node.OutEdges.Count() == 0 && x_node.SelfEdges.Count() == 0)
                {
                    glee_fsm_graph.NodeMap.Remove(x_node.Id);
                }

            }

            //display every other node with in or out nodes
            
            foreach (Transition t in machine_.transitions)
            {
                if (t.isMitigationPoint == true)
                {
                    int index = 0;
                    foreach (Edge edge in edges)
                    {
                        string[] l_s = edge.LabelText.Split('(');
                        string t_label_n = l_s[0];
                        if (t_label_n.Equals(t.transitionName))
                        {
                            Edge e_n = glee_fsm_graph.Edges.ElementAt(index);
                            if (e_n != null)
                            {
                                e_n.Attr.Color = Microsoft.Msagl.Drawing.Color.YellowGreen;
                            }
                        }
                        index = index + 1;
                    }
                }

                if (t.isMisusePoint == true)
                {
                    int index = 0;
                    foreach (Edge edge in edges)
                    {
                        string[] l_s = edge.LabelText.Split('(');
                        string t_label_n = l_s[0];
                        if (t_label_n.Equals(t.transitionName))
                        {
                            Edge e_n = glee_fsm_graph.Edges.ElementAt(index);
                            if (e_n != null)
                            {
                                e_n.Attr.Color = Microsoft.Msagl.Drawing.Color.OrangeRed;
                            }
                        }
                        index = index + 1;
                    }
                }
            }

            foreach (State s in machine_.states)
            {
                bool isMisuseAct = false;
                foreach (PMisuseAn.behaviour.model.Action action in s.actions)
                {
                    if (action.isMitigationPoint == true)
                    {
                        string key = null;                       
                        foreach (DictionaryEntry entry in nodes)
                        {
                            Node n = (Node)entry.Value;
                            if (n.LabelText.Equals(s.name))
                            {
                                key = (string)entry.Key;
                                break;
                            }
                        }

                        if (key != null)
                        {
                            Node s_n = glee_fsm_graph.FindNode(key);
                            if (s_n != null && isMisuseAct == false)
                            {
                                s_n.Label.FontColor = Microsoft.Msagl.Drawing.Color.GreenYellow;
                            }
                        }
                    }

                    if (action.isMisusePoint == true)
                    {
                        string key = null;
                        foreach (DictionaryEntry entry in nodes)
                        {
                            if (entry.Value.ToString().Contains(s.name))
                            {
                                key = (string)entry.Key;
                                break;
                            }
                        }

                        if (key != null)
                        {
                            Node s_n = glee_fsm_graph.FindNode(key);
                            if (s_n != null)
                            {
                                s_n.Label.FontColor = Microsoft.Msagl.Drawing.Color.DarkRed;
                                isMisuseAct = true;
                            }
                        }
                    }
                }

                if (s.isMitigationPoint == true)
                {
                    string key = null;
                    foreach (DictionaryEntry entry in nodes)
                    {
                        if (entry.Value.ToString().Contains(s.name))
                        {
                            key = (string)entry.Key;
                            break;
                        }
                    }

                    if (key != null)
                    {
                        Node s_n = glee_fsm_graph.FindNode(key);
                        if (s_n != null)
                        {
                            s_n.Attr.FillColor = Microsoft.Msagl.Drawing.Color.LightYellow;
                        }
                    }
                }

                if (s.isMisusePoint == true)
                {
                    string key = null;
                    foreach (DictionaryEntry entry in nodes)
                    {
                        if (entry.Value.ToString().Contains(s.name))
                        {
                            key = (string)entry.Key;
                            break;
                        }
                    }

                    if (key != null)
                    {
                        Node s_n = glee_fsm_graph.FindNode(key);
                        if (s_n != null)
                        {
                            s_n.Attr.FillColor = Microsoft.Msagl.Drawing.Color.OrangeRed;
                        }
                    }
                }
            }

            if (startState != null)
            {
                string start_key = "";
                foreach (DictionaryEntry entry in nodes)
                {
                    if (entry.Value.ToString().Contains(startState))
                    {
                        start_key = (string)entry.Key;
                        break;
                    }
                }
                Node s_n = glee_fsm_graph.FindNode(start_key);
                if (s_n != null)
                {
                    s_n.Attr.LineWidth = 5;
                    //s_n.Attr.Fillcolor = Microsoft.Glee.Drawing.Color.Green;
                }
            }           

            viewer.Graph = glee_fsm_graph;
            //viewer.SetBounds(319,278,0,0);
            viewer.BackColor = System.Drawing.Color.White;
            viewer.Dock = System.Windows.Forms.DockStyle.Fill;

            this.fsm_wfh.Child = viewer;
        }

        Graph CreateFSMGraph(string machineName_)
        {
            machine_ = MisUseAnObjectsDB.loadStateMachineDB(machineName_, MainWindow.clusterName);
            startState = MisUseAnObjectsDB.getStartState(machineName_, MainWindow.clusterName);
            endState = MisUseAnObjectsDB.getEndState(machineName_, MainWindow.clusterName);

            // Create an FSM.
            Graph fsm = new Graph();

            foreach (State s in machine_.states)
            {
                Node node = new Node(s.name);
                if (startState != null && s.name.Equals(startState))
                {
                    node.Attr.Shape = Microsoft.Msagl.Drawing.Shape.DoubleCircle;
                    node.Attr.AddStyle(Microsoft.Msagl.Drawing.Style.Rounded);
                }
                else if (endState != null && s.name.Equals(endState))
                {
                    node.Attr.Shape = Microsoft.Msagl.Drawing.Shape.Circle;
                    //node.Attr.FillColor = Microsoft.Msagl.Drawing.Color.Gray;
                    node.Attr.AddStyle(Microsoft.Msagl.Drawing.Style.Bold);
                    node.Attr.AddStyle(Microsoft.Msagl.Drawing.Style.Dashed);

                }
                else
                {

                    node.Attr.Shape = Microsoft.Msagl.Drawing.Shape.Circle;
                }
                fsm.AddNode(node);
            }

            foreach (Transition t in machine_.transitions)
            {
                string desc = t.transitionName + "(" + t.associatedEevent + ")";
                fsm.AddEdge(t.startState, desc, t.endState);
            }    
            
            return fsm;
        }


        //public void del_state_machine_Click(object sender, RoutedEventArgs e)
        //{
        //    MessageBoxResult result = MessageBox.Show("Confirm delete...", "Delete", MessageBoxButton.YesNo, MessageBoxImage.Question);
        //    if (result == MessageBoxResult.No)
        //    {
        //        return;
        //    }

        //    Button d_b = (Button)sender;
        //    string tag_id = (string)d_b.Tag;
        //    MisUseAnObjectsDB.deleteStateMachineDB(tag_id, MainWindow.clusterName);

        //    //machines_trg.Rows.Clear();
        //    fsm_lb.Items.Clear();
        //    //loadMachines();
        //    loadFiniteStatemachines();
        //}

        public void open_state_machine_b_Click(object sender, RoutedEventArgs e)
        {
            Button a_b = (Button)sender;
            string machine_name = (String)a_b.Tag;
            StateMachine machine = MisUseAnObjectsDB.loadStateMachineDB(machine_name, MainWindow.clusterName);
            AddStateMachineWindow asmw = new AddStateMachineWindow(this, machine);
            asmw.Owner = (Window)this.Parent;
            asmw.ShowDialog();
        }

        public void open_att_b_Click(object sender, RoutedEventArgs e)
        {
            Button a_b = (Button)sender;
            Attribute att = (Attribute)a_b.Tag;
            Attribute full_att = MisUseAnObjectsDB.loadAttributeFull(att.name, MainWindow.clusterName);
            AddActorAttributeWindow acw = new AddActorAttributeWindow(this, full_att);
            acw.Owner = (Window)this.Parent;
            acw.ShowDialog();
        }

        public void open_actor_b_Click(object sender, RoutedEventArgs e)
        {
            Button a_b = (Button)sender;
            string actor_name = (String)a_b.Tag;
            Actor actor = MisUseAnObjectsDB.loadActor(actor_name, MainWindow.clusterName);
            AddActorWindow aaw = new AddActorWindow(this, actor);
            aaw.Owner = (Window)this.Parent;
            aaw.ShowDialog();
        }

        public void del_att_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult result = MessageBox.Show("Confirm delete...", "Delete", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (result == MessageBoxResult.No)
            {
                return;
            }

            MenuItem d_b = (MenuItem)sender;
            Attribute tag_id = (Attribute)d_b.Tag;
            MisUseAnObjectsDB.deleteAttribute(tag_id, MainWindow.clusterName);

            loadDomainAttributes();
        }

        public void del_actor_Click(object sender, RoutedEventArgs e)
        {

            MessageBoxResult result = MessageBox.Show("Confirm delete...", "Delete", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (result == MessageBoxResult.No)
            {
                return;
            }

            MenuItem d_b = (MenuItem)sender;
            string tag_id = (string)d_b.Tag;
            MisUseAnObjectsDB.deleteActor(tag_id, MainWindow.clusterName);

            loadActors();

        }

        private void policy_b_Click(object sender, RoutedEventArgs e)
        {
            AddPolicyWindow1 apw = new AddPolicyWindow1(this);
            apw.Owner = (Window)this.Parent;
            apw.ShowDialog();
        }


        private void primary_actor_b_Click(object sender, RoutedEventArgs e)
        {
            AddActorWindow aaw = new AddActorWindow(this);
            aaw.Owner = (Window)this.Parent;
            aaw.ShowDialog();
        }

        private void add_att_b_Click(object sender, RoutedEventArgs e)
        {
            AddActorAttributeWindow acw = new AddActorAttributeWindow(this);
            acw.isNewAttribute = true;
            acw.Owner = (Window)this.Parent;
            acw.ShowDialog();
        }

        private void refresh_att_Button_Click(object sender, RoutedEventArgs e)
        {
            loadDomainAttributes();
        }

        private void use_cases_b_Click(object sender, RoutedEventArgs e)
        {
            string machine_name = new_state_machine_name.Text;
            machine_name = machine_name.Trim();
            machine_name = machine_name.TrimEnd('\n');
            machine_name = machine_name.TrimEnd('\r');

            if (machine_name.Count() == 0)
            {
                MessageBoxResult result = MessageBox.Show("NULL machine name...",
                            "error", MessageBoxButton.OK,
                            MessageBoxImage.Information);
                return;
            }
            
            List<string> machines = MisUseAnObjectsDB.loadAllmachines(MainWindow.clusterName);
            bool invalidName = false;
            foreach (string m in machines)
            {
                if (m.Equals(machine_name))
                {
                    invalidName = true;
                }
            }
            if (invalidName)
            {
                MessageBoxResult result = MessageBox.Show("Duplicate machine names not allowed",
                            "error", MessageBoxButton.OK,
                            MessageBoxImage.Information);
                return;
            }

            AddStateMachineWindow asmw = new AddStateMachineWindow(this, machine_name);
            asmw.Owner = (Window)this.Parent;
            asmw.ShowDialog();
            new_state_machine_name.Text = "";

        }

        private void refresh_FSMs_b_Click(object sender, RoutedEventArgs e)
        {
            loadFiniteStatemachines();
        }

        public void loadProjectNamesToMenu()
        {
            List<string> clusters = MisUseAnObjectsDB.loadAllClusters();
            open_project.Items.Clear();
            foreach (string cluster in clusters)
            {
                MenuItem item = new MenuItem();
                item.Header = cluster;
                item.Tag = cluster;
                item.AddHandler(MenuItem.ClickEvent, new RoutedEventHandler(open_cluser_clicked));

                open_project.Items.Add(item);
            }
        }

        private void open_cluser_clicked(object sender, RoutedEventArgs e)
        {
            MenuItem d_b = (MenuItem)sender;
            string tag_id = (string)d_b.Tag;
            MainWindow.clusterName = tag_id;
            loadContextInterface();
            this.fsm_wfh.Child = null;
        }

        private void new_project_Click(object sender, RoutedEventArgs e)
        {
            this.fsm_wfh.Child = null;
            NewClusterWindow ncw = new NewClusterWindow(this);
            ncw.Owner = (Window)this.Parent;
            ncw.ShowDialog();
        }

        private void delete_project_Click(object sender, RoutedEventArgs e)
        {
            if (MainWindow.clusterName == null || MainWindow.clusterName.Count() == 0)
            {
                MessageBox.Show("Project not defined", "Error", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            MessageBoxResult result = MessageBox.Show("Delete "+MainWindow.clusterName+" project", "Confirm", MessageBoxButton.YesNo, MessageBoxImage.Question);

            if (result == MessageBoxResult.No)
            {
                return;
            }
            MisUseAnObjectsDB.deleteClusterDB(MainWindow.clusterName);

            MainWindow.clusterName = "";
            project_name_l.Content = MainWindow.clusterName;
            
            this.fsm_wfh.Child = null;

            InitializeComponent();
            tabControl1.Visibility = System.Windows.Visibility.Hidden;
            fsm_grid.Visibility = System.Windows.Visibility.Hidden;
            loadProjectNamesToMenu();
        }

        private void configAgentGroup_b_Click(object sender, RoutedEventArgs e)
        {
            GroupConfigWindow agcw = new GroupConfigWindow();
            agcw.Owner = (Window)this.Parent;
            agcw.ShowDialog();

            loadFiniteStatemachines();
        }

        private void emulate_b_Click(object sender, RoutedEventArgs e)
        {
            EmulationEnvironmentWindow eew = new EmulationEnvironmentWindow();
            eew.Owner = (Window)this.Parent;
            eew.ShowDialog();
        }

        ///////////////////

        //Create a Delegate that matches 
        //the Signature of the ProgressBar's SetValue method
        private delegate void UpdateProgressBarDelegate(
                System.Windows.DependencyProperty dp, Object value);
        
        private void initProgress()
        {
            //Configure the ProgressBar
            progressBar1.Visibility = System.Windows.Visibility.Visible;
            progressBar1.Minimum = 0;
            progressBar1.Maximum = 5;
            progressBar1.Value = 0;

            progressValue = 1;

            //Stores the value of the ProgressBar
            

            //Create a new instance of our ProgressBar Delegate that points
            // to the ProgressBar's SetValue method.
            updatePbDelegate =
                new UpdateProgressBarDelegate(progressBar1.SetValue);

        }
        private void UpdateProgressBar()
        {
            if (progressBar1.Value != progressBar1.Maximum)
            {
                progressValue += 1;

                Dispatcher.Invoke(updatePbDelegate,
                    System.Windows.Threading.DispatcherPriority.Background,
                    new object[] { ProgressBar.ValueProperty, progressValue });
            }
            
        }
        private void removeProgressBar()
        {
            progressBar1.Visibility = System.Windows.Visibility.Hidden;
        }

        ////////////////////////////
    }
}
